<template>
    <div class="map-container">
        <div id="map" class="gis-map"></div>
        <div class="tool">
            <a-select show-search :filter-option="filterOption" option-filter-prop="children" style="width: 100px;margin-right: 20px" allowClear v-model="searchCity" placeholder="请选择城市">
                <a-select-option v-for="item in cityList" :key="item.value" :value="item.label">{{ item.label }}</a-select-option>
            </a-select>
            <a-select
                show-search
                :value="searchName"
                :default-active-first-option="false"
                :show-arrow="false"
                :filter-option="false"
                :not-found-content="null"
                placeholder="请输入搜索内容" style="width: 350px;margin-right: 20px"
                @search="searchLocationName"
                @change="searchChange"
            >
                <a-select-option v-for="item in searchList" :key="item.hotPointID" :value="item.hotPointID">{{ item.name }}-{{item.address}}</a-select-option>
            </a-select>
        </div>
    </div>
</template>
<script>
import axios from "axios";
import areaJson from "@/utils/area";

function debounce(func,wait) {
    let timeout;

    return function(...args) {
        const context = this;

        clearTimeout(timeout);
        timeout = setTimeout(() => func.apply(context, args), wait);
    };
}
export default {
    props:['center','mapLayer','disabled'],
    name: "gisMap",
    data() {
        return {
            map:null,
            update:true,
            marker:null,
            searchCity:'北京市',
            cityList:[],
            searchName:'',
            selectedLocation:undefined,
            searchList:[],
            apiKeys: [
                '5c68d0d10d0fa048192d148108ba00b9', // 项目原本key
                '8b94e951fdd8ef3dce4b5153362e8f08', // sameki key
                '027fa055be0f270ee79ea246b7457ce6', // 原链企业账号key
                '7f398b21619c5b414899d630b388100b', // xls key
                '41252f44578a99fda1a999538d537df3', // duan key
            ],
            currentApiKeyIndex: 0, // 当前使用的key索引
            maxRetries: 3, // 最大重试次数
            retryCount:0,//重试次数
            TK_KEY:'',//当前key
            debouncedMapLoadSuccess:null,
            debounceSearch:null,
        }
    },
    watch: {
        center() {
            this.initLeaftMap()
        }
    },
    created() {
        // 创建防抖函数实例
        this.debouncedMapLoadSuccess = debounce(this.mapLoadSuccess, 2000);
        this.debounceSearch = debounce(this.searchLocationName, 1000);
    },
    mounted() {
        this.cityList = areaJson
        setTimeout(()=>{
            console.log('地图初始化完成，中心点：',this.center)
            this.initLeaftMap()
        },500)
    },
    methods:{
        mapLoadSuccess() {
            this.$message.success('地图已成功加载');
        },
        filterOption(input, option) {
            return (
                option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
            );
        },
        //写一个普通的防抖

        initLeaftMap() {
            if (this.map) this.map.remove();
            this.map = null;
            //限制地图的拖动范围是正负90到正负180，这样才合理。
            var corner1 = L.latLng(-90, -180); //设置左上角经纬度
            var corner2 = L.latLng(90, 180);	//设置右下点经纬度
            var bounds = L.latLngBounds(corner1, corner2); //构建视图限制范
            //自定义leaflet天地图经纬度坐标
            //设置地图相关初始配置
            this.map = L.map("map", {
                center:this.center,
                minZoom:2,
                maxZoom: 17,
                preferCanvas:true,
                zoom: 10, //初始地图缩放级别
                crs: L.CRS.EPSG4326,//设置坐标系4326
                scrollWheelZoom: true, //默认开启鼠标滚轮缩放
                zoomControl: false, //禁用 + - 按钮
                doubleClickZoom: false, // 禁用双击放大
                attributionControl: false, // 移除右下角leaflet标识
                maxBounds: bounds,
            });
            this.TK_KEY = this.apiKeys[this.currentApiKeyIndex];
            // 底图
            //vec_c 交通标记
            const vec_c = 'http://{s}.tianditu.gov.cn/vec_c/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=c&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk='
            //cta_c 地名地点标记
            const cta_c = 'http://{s}.tianditu.gov.cn/cta_c/wmts?layer=cta&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=';
            //img_c 卫星地图
            const img_c = 'http://{s}.tianditu.gov.cn/img_c/wmts?layer=img&style=default&tilematrixset=c&Service=WMTS&Request=GetTile&Version=1.0.0&Format=tiles&TileMatrix={z}&TileCol={x}&TileRow={y}&tk=';
            if(this.mapLayer){
                let vec_cLayer = L.tileLayer(vec_c + this.TK_KEY, {
                    maxZoom: 18,
                    tileSize: 256,
                    zoomOffset: 1,
                    subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
                }, { noWrap: false }).addTo(this.map);
                let cta_cLayer = L.tileLayer(cta_c + this.TK_KEY, {
                    maxZoom: 18,
                    tileSize: 256,
                    zoomOffset: 1,
                    subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
                }, { noWrap: false }).addTo(this.map);
                //防抖
                vec_cLayer.on('load', this.debouncedMapLoadSuccess);
                vec_cLayer.on('tileerror',()=>{
                    this.$message.error('检测到图层加载失败，尝试使用新的key加载地图图层')
                    //删除当前加载失败的图层
                    this.map.removeLayer(cta_cLayer);
                    this.map.removeLayer(vec_cLayer);
                    setTimeout(()=>{
                        this.$message.error(`当前尝试次数：${this.retryCount+1}次,已删除当前加载失败的图层，尝试加载新图层中...`)
                        this.changeApiKey();
                    },1000)
                });
            }else{
                let img_cLayer = L.tileLayer(img_c + this.TK_KEY, {
                    maxZoom: 18,
                    tileSize: 256,
                    zoomOffset: 1,
                    subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
                }, { noWrap: false}).addTo(this.map);
                let cta_cLayer = L.tileLayer(cta_c + this.TK_KEY, {
                    maxZoom: 18,
                    tileSize: 256,
                    zoomOffset: 1,
                    subdomains: ['t0', 't1', 't2', 't3', 't4', 't5', 't6', 't7'],
                }, { noWrap: false }).addTo(this.map);
                //防抖
                img_cLayer.on('load', this.debouncedMapLoadSuccess);
                img_cLayer.on('tileerror',()=>{
                    this.$message.error('检测到图层加载失败，尝试使用新的key加载地图图层')
                    //删除当前加载失败的图层
                    this.map.removeLayer(cta_cLayer);
                    this.map.removeLayer(img_cLayer);
                    setTimeout(()=>{
                        this.$message.error(`当前尝试次数：${this.retryCount+1}次,已删除当前加载失败的图层，尝试加载新图层中...`)
                        this.changeApiKey();
                    },1000)
                });
            }
            //如果有中心点，也就是marker坐标直接添加maker到地图
            if(this.center.length){
                this.marker = L.marker(this.center, {
                    draggable: true,
                    icon: L.icon({
                        iconUrl: require('@/assets/img/logo-ico.png'),
                        iconSize: [30, 30],
                        iconAnchor: [15, 30],
                        popupAnchor: [0, -30]
                    })
                }).addTo(this.map);
                this.marker.bindPopup(`经度：${this.center[0]}<br>纬度：${this.center[1]}`).openPopup();
            }
            if(this.disabled){
                return
            }
            // 监听点击事件
            this.map.on('click', this.onMapClick);
        },
        changeApiKey() {
            this.currentApiKeyIndex = (this.currentApiKeyIndex + 1) % this.apiKeys.length;
            if(this.currentApiKeyIndex > this.apiKeys.length-1){
                console.log('已遍历完key,正在尝试寻找可用的key')
                //重置使用key组的第一个key
                this.currentApiKeyIndex = 0;
            }
            //最大尝试次数超过key组长度或key组不足3个则不再尝试
            this.retryCount ++
            if(this.retryCount >= (this.maxRetries = this.apiKeys.length>=3 ? this.apiKeys.length:this.maxRetries)){
                setTimeout(()=>{
                    this.$message.error('超过尝试次数，但均无法加载地图，请联系管理员')
                },3000)
                return
            }
            this.TK_KEY = this.apiKeys[this.currentApiKeyIndex];
            console.log(`Switched to API key: ${this.TK_KEY}`);
            setTimeout(()=>{
                this.$message.success('已成功切换key,正在尝试重新加载地图')
                this.initLeaftMap()

            },4000)
        },
        onMapClick(e) {
            // 移除旧的标记
            if (this.marker) {
                this.map.removeLayer(this.marker);
            }

            // 创建新标记
            this.marker = L.marker([e.latlng.lat, e.latlng.lng], {
                draggable: true,
                icon: L.icon({
                    iconUrl: require('@/assets/img/logo-ico.png'),
                    iconSize: [30, 30],
                    iconAnchor: [15, 30],
                    popupAnchor: [0, -30]
                })
            }).addTo(this.map);
            this.marker.bindPopup(`经度：${e.latlng.lng}<br>纬度：${e.latlng.lat}`).openPopup();
            this.$emit('markerLngLat', [e.latlng.lng,e.latlng.lat])
        },
        searchChange(v){
            this.moveTo(v)
        },
        async searchLocationName(v) {
            if(!this.searchCity){
                this.$message.error('请选择城市')
                return
            }
            let params = {
                postStr: {
                    keyWord:v,
                    queryType: '12',
                    start: '0',
                    count: '50',
                    specify: this.searchCity,
                    show:'2'
                },
                // type: 'query',
                tk: '5c68d0d10d0fa048192d148108ba00b9'
            }
            params.postStr = JSON.stringify(params.postStr)
            const res = await axios.get('https://api.tianditu.gov.cn/v2/search', {
                params: params,
            })
            if(res.status == 200){
                let data = res.data
                if(data.area){
                    let location = data.area.lonlat.split(',')
                    this.map.setView([location[1], location[0]],10)
                    this.searchList = []
                    this.searchName = data.keyWord
                }else{
                    if(data.pois){
                        this.searchList = data.pois
                    }else{
                        this.$message.error('暂无搜索结果')
                        this.searchList = []
                    }
                }
            }
        },
        //移动到搜索的位置
        moveTo(v) {
            if(v){
                let find = this.searchList.find(item=>item.hotPointID == v)
                this.searchName = find.name
                if(find){
                    let location = find.lonlat.split(',')
                    let lat = location[1]*1
                    let lng = location[0]*1
                    this.map.setView([lat, lng],13)
                }

            }
        }
    },
}
</script>
<style scoped lang="scss">
.map-container{
    width: 100%;
    height: 100%;
    .gis-map{
        position: relative;
        width: 100%;
        height: 100%;
    }
}
.tool{
    z-index: 1000;
    position: absolute;
    right: 10px;
    top: 20px;
}
</style>
